package sk.stuba.fiit.pki.core;

import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Date;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cms.SignerInfoGenerator;
import org.bouncycastle.tsp.TSPAlgorithms;
import org.bouncycastle.tsp.TSPException;
import org.bouncycastle.tsp.TimeStampRequest;
import org.bouncycastle.tsp.TimeStampRequestGenerator;
import org.bouncycastle.tsp.TimeStampResponse;
import org.bouncycastle.tsp.TimeStampResponseGenerator;
import org.bouncycastle.tsp.TimeStampToken;
import org.bouncycastle.tsp.TimeStampTokenGenerator;
import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;
import org.bouncycastle.x509.X509Store;
import org.bouncycastle.x509.X509V3CertificateGenerator;

public class TimeStampManager {
	
	private static TimeStampManager manager;
	
	public static TimeStampManager getInstance(){
		if(manager == null){
			return new TimeStampManager();
		}
		return manager;
	}
	
	private X509Certificate cer;
	private PrivateKey key;

	 public TimeStampResponse processTimestampResponse(TimeStampRequest request,PrivateKey key,X509Certificate certificate, BigInteger serialNumber) throws IllegalArgumentException, TSPException, IOException, GeneralSecurityException{
		 TimeStampTokenGenerator timestamptokengenerator = new TimeStampTokenGenerator(key, certificate, request.getMessageImprintAlgOID(), "1.2");
         TimeStampResponseGenerator timestampresponsegenerator = new TimeStampResponseGenerator(timestamptokengenerator, TSPAlgorithms.ALLOWED);
         
         TimeStampResponse timestampresponse = timestampresponsegenerator.generate(request, serialNumber, new Date(),"BC");
	        TimeStampToken timestamptoken = timestampresponse.getTimeStampToken();
	        timestamptoken.validate(certificate, "BC");
	        AttributeTable attributetable = timestamptoken.getSignedAttributes();
	        return timestampresponse;
    }
	
	 public TimeStampRequest generateRequest() throws NoSuchAlgorithmException, NoSuchProviderException{
		 
		 TimeStampRequestGenerator generator = new TimeStampRequestGenerator();
			ASN1ObjectIdentifier asn1objectidentifier = TSPAlgorithms.SHA1;		
			BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());		
			MessageDigest hash = MessageDigest.getInstance("SHA1", "BC");
			byte[] data = new byte[]{0x3,0x34,0x3,0x34,0x3,0x34,0x3,0x34,0x3,0x34};
			hash.update(data);		
			TimeStampRequest timestamprequest = generator.generate(asn1objectidentifier, hash.digest(), nonce);	
			return timestamprequest;
	 }
	 
	 public static void main(String[] args) throws Exception {
TimeStampManager tsm = new TimeStampManager();
TimeStampRequest timestamprequest = tsm.generateRequest();
TimeStampResponse resp = tsm.processTimestampResponse(timestamprequest, null, null, new BigInteger("1"));
BigInteger serial = resp.getTimeStampToken().getTimeStampInfo().getSerialNumber();
byte[] digest = resp.getTimeStampToken().getTimeStampInfo().getMessageImprintDigest();

MessageDigest hash = MessageDigest.getInstance("SHA1", "BC");
byte[] data = new byte[]{0x3,0x34,0x3,0x34,0x3,0x34,0x3,0x34,0x3,0x34};
hash.update(data);
byte [] res = hash.digest();

for(int i = 0; i< digest.length; i++){
	System.out.print(digest[i]&0xff);
}
System.out.println();
for(int i = 0; i< digest.length; i++){
	System.out.print(res[i]&0xff);
}


Store store = resp.getTimeStampToken().getCertificates();
System.out.println(serial);
	}
}
